#include "LightingManager.h"
#include "ObjMeshManager.h"
#include "DX11ErrorReport.h"
#include "StringUtilities.h"
#include "AntTweakBarManager.h"

LightingManager::LightingManager()
{
	D3DXMatrixIdentity(&m_viewMatrix);
	D3DXMatrixIdentity(&m_projMatrix);

	// set default light
	Light* l = new Light;
	l->ambient = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
	l->colour = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
	l->direction = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->position = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->attenuation = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->range = 100.0f;
	l->enabled = 2; // 2 = default light for shader
	l->pad = D3DXVECTOR2(0, 0);
	m_lights[0] = *l; // light 0 = default light

	l->ambient = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
	l->colour = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);
	l->direction = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);
	l->position = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->attenuation = D3DXVECTOR4(0.0f, 0.2f, 0.0f, 1.0f);
	l->range = 100.0f;
	l->enabled = 0;
	l->pad = D3DXVECTOR2(0, 0);
	m_lights[1] = *l;
	
	l->ambient = D3DXVECTOR4(0.5f, 0.5f, 0.5f, 1.0f);
	l->colour = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->direction = D3DXVECTOR4(0.0f, 0.0f, -1.0f, 1.0f);
	l->position = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->attenuation = D3DXVECTOR4(0.0f, 0.2f, 0.0f, 1.0f);
	l->range = 100.0f;
	l->enabled = 0;
	l->pad = D3DXVECTOR2(0, 0);
	m_lights[2] = *l;

	l->ambient = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->colour = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->direction = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->position = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f);
	l->attenuation = D3DXVECTOR4(0.0f, 0.2f, 0.0f, 1.0f);
	l->range = 100.0f;
	l->enabled = 0;
	l->pad = D3DXVECTOR2(0, 0);
	m_lights[3] = *l;
	delete l;

	m_numOfLights = m_lights.size() - 1; // -1 because of the default light
	m_enabled = true;
	m_drawLights = true;

	TheObjMeshManager::Instance()->LoadObj("../../Assets/lightbulb.obj", "lightbulb", L"LightBulbShader.hlsl");
}

void LightingManager::SetLight(int lightNum, const Light& light)
{
	m_lights[lightNum] = light;
}

const Light& LightingManager::GetLight(int lightNum)
{
	if (m_enabled)
	{
		CheckLight(lightNum);
		return m_lights[lightNum];
	}
	else
	{
		return m_lights[0];
	}
}

void LightingManager::Draw(int lightNum)
{
	if (m_drawLights)
	{
		CheckLight(lightNum);

		D3DXVECTOR4 lightPos = m_lights[lightNum].direction;
		D3DXVECTOR4 lightAmb = m_lights[lightNum].ambient;
		m_lights[lightNum].ambient = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);

		TheObjMeshManager::Instance()->SetColour("lightbulb", m_lights[lightNum].colour);
		TheObjMeshManager::Instance()->Scale("lightbulb", 256, 256, 256);
		TheObjMeshManager::Instance()->Translate("lightbulb", -lightPos.x, 0.0f, -lightPos.z);

		if (lightPos.y > 0)
		{
			TheObjMeshManager::Instance()->Scale("lightbulb",	0.03125f * (lightPos.y + 1.0f), 
																0.03125f * (lightPos.y + 1.0f), 
																0.03125f * (lightPos.y + 1.0f));
		}
		else
		{
			TheObjMeshManager::Instance()->Scale("lightbulb",	0.03125f * 1.0f, 
																0.03125f * 1.0f, 
																0.03125f * 1.0f);
		}

		TheObjMeshManager::Instance()->Draw("lightbulb");

		m_lights[lightNum].ambient = lightAmb;
	}
}

void LightingManager::DrawAll()
{
	for (LightMap::iterator it = m_lights.begin(); it != m_lights.end(); ++it)
	{
		D3DXVECTOR4 lightPos = it->second.direction;
		D3DXVECTOR4 lightAmb = it->second.ambient;
		it->second.ambient = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);

		//TheObjMeshManager::Instance()->
		TheObjMeshManager::Instance()->Translate("lightbulb", -lightPos.x, lightPos.y, -lightPos.z);
		TheObjMeshManager::Instance()->Draw("lightbulb");

		it->second.ambient = lightAmb;
	}
}

const void LightingManager::CheckLight(int lightNum)
{
	LightMap::iterator it = m_lights.find(lightNum);

	if(it == m_lights.end())
	{
		std::string lightnumber = ToString(lightNum);
		std::wstring errorMsg;
		errorMsg.assign(lightnumber.begin(), lightnumber.end());
		errorMsg = L"No such light: " + errorMsg;
		DX11ErrorMsg(errorMsg.c_str(), L"ObjMeshManager", MB_YESNO);
	}
}

void LightingManager::Disable(int lightNum)
{
	m_lights[lightNum].enabled = 0;
}

void LightingManager::Enable(int lightNum)
{
	m_lights[lightNum].enabled = 1;
}

void LightingManager::DisableLighting()
{
	m_enabled = false;
}

void LightingManager::EnableLighting()
{
	m_enabled = true;
}

void LightingManager::SetLightViewMatrix(const D3DXMATRIX& m)
{
	m_viewMatrix = m;
}

const D3DXMATRIX& LightingManager::GetLightViewMatrix() const 
{
	return m_viewMatrix;
}

void LightingManager::SetLightProjMatrix(const D3DXMATRIX& m)
{
	m_projMatrix = m;
}

const D3DXMATRIX& LightingManager::GetLightProjMatrix() const
{
	return m_projMatrix;
}

void LightingManager::SetLightMatrices(const D3DXMATRIX& view, const D3DXMATRIX& proj)
{
	m_viewMatrix = view;
	m_projMatrix = proj;
}